package es.uned.etsii.si3.taller.servlets;

import java.sql.SQLException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Map;

import org.apache.struts2.interceptor.SessionAware;

import com.j256.ormlite.stmt.QueryBuilder;
import com.j256.ormlite.stmt.Where;
import com.opensymphony.xwork2.ActionSupport;

import es.uned.etsii.si3.taller.Empleado;
import es.uned.etsii.si3.taller.EmpleadoTaller;
import es.uned.etsii.si3.taller.FactoriaDAO;
import es.uned.etsii.si3.taller.FactoriaFunciones;
import es.uned.etsii.si3.taller.ParteTrabajo;
import es.uned.etsii.si3.taller.Reparacion;
import es.uned.etsii.si3.taller.Trabajo;
import es.uned.etsii.si3.taller.Usuario;
import es.uned.etsii.si3.taller.misc.ProporcionaFuncionalidad;

public class JSReparacionesRecepcionadas extends ActionSupport implements SessionAware {

	private static final long serialVersionUID = 1L;

	private  	Map<String, Object>		userSession;
	
	private		EmpleadoTaller			datosEmpleado;
	public		EmpleadoTaller			getDatosEmpleado()							{ return this.datosEmpleado; }
	public		void 					setDatosEmpleado(Usuario uS) throws SQLException {
		QueryBuilder<EmpleadoTaller, Integer> eTQb;
		eTQb = FactoriaDAO.getDao(EmpleadoTaller.class).queryBuilder();
		Where<EmpleadoTaller, Integer> wETQb = eTQb.where();			
		wETQb.eq(EmpleadoTaller.ID_USUARIO_FIELD_NAME, uS);			
		List<EmpleadoTaller> lista = wETQb.query();
		this.datosEmpleado = lista.get(0);
	}
	
	private 	ParteTrabajo			parteSeleccionado = null;
	public 		ParteTrabajo			getParteSeleccionado() 						{ return this.parteSeleccionado; }
	public 		void					setParteSeleccionado(ParteTrabajo pT) 		{ this.parteSeleccionado = pT; }

	private 	static int 				parteSeleccionadoID = -1;
	public 		int						getParteSeleccionadoID() 					{ return parteSeleccionadoID; }
	public 		void					setParteSeleccionadoID(int i) 				{ parteSeleccionadoID = i; }
	
	private 	Reparacion				reparacionSeleccionado = null;
	public 		Reparacion				getReparacionSeleccionado()					{ return this.reparacionSeleccionado; }
	public 		void					setReparacionSeleccionado(Reparacion r)		{ this.reparacionSeleccionado = r; }

	private 	static int 				reparacionSeleccionadoID = -1;
	public 		int						getReparacionSeleccionadoID() 				{ return reparacionSeleccionadoID; }
	public 		void					setReparacionSeleccionadoID(int i) 			{ reparacionSeleccionadoID = i; }

	private 	Trabajo					trabajoSeleccionado = null;
	public 		Trabajo					getTrabajoSeleccionado() 					{ return this.trabajoSeleccionado; }
	public 		void					setTrabajoSeleccionado(Trabajo t)	 		{ this.trabajoSeleccionado = t; }

	private 	static int 				trabajoSeleccionadoID = -1;
	public 		int						getTrabajoSeleccionadoID() 					{ return trabajoSeleccionadoID; }
	public 		void					setTrabajoSeleccionadoID(int i)				{ trabajoSeleccionadoID = i; }

	private		Empleado				mecanicoSeleccionado = null;
	public 		Empleado				getMecanicoSeleccionado() 					{ return mecanicoSeleccionado; }
	public 		void					setMecanicoSeleccionado(Empleado e) 		{ mecanicoSeleccionado = e; }

	private	 	static int 				mecanicoSeleccionadoID = -1;
	public 		int						getMecanicoSeleccionadoID() 				{ return mecanicoSeleccionadoID; }
	public 		void					setMecanicoSeleccionadoID(int i) 			{ mecanicoSeleccionadoID = i; }

	private 	List<Reparacion>		listaReparaciones;
	public		List<Reparacion>		getListaReparaciones()						{ return this.listaReparaciones; }
	public		void					setListaReparaciones(List<Reparacion> l)	{ this.listaReparaciones = l; }

	private 	List<Trabajo>			listaTrabajos;
	public		List<Trabajo>			getListaTrabajos()							{ return this.listaTrabajos; }
	public		void					setListaTrabajos(List<Trabajo> l)			{ this.listaTrabajos = l; }
	
	private 	List<Empleado>			listaMecanicos;
	public		List<Empleado>			getListaMecanicos()							{ return this.listaMecanicos; }
	public		void					setListaMecanicos(List<Empleado> l)			{ this.listaMecanicos = l; }

	private		String					nombreSeccion;
	public		String					getNombreSeccion()							{ return this.nombreSeccion; }
	public 		void					setNombreSeccion() 
								{ this.nombreSeccion = this.getDatosEmpleado().getSeccion().getTipoSeccion().getNombre(); }
	
	private 	String					fechaRecepcionString;
	public		String					getFechaRecepcionString()					{ return this.fechaRecepcionString; }
	public		void					setFechaRecepcionString(String s)			{ this.fechaRecepcionString = s; }

	private 	String					fechaEstimadaString;
	public		String					getFechaEstimadaString()					{ return this.fechaEstimadaString; }
	public		void					setFechaEstimadaString(String s)			{ this.fechaEstimadaString = s; }
	
	private		String					descripcion;
	public		String					getDescripcion()							{ return this.descripcion; }
	public		void					setDescripcion(String s)					{ this.descripcion = s; }
	
	private		int						siguiente;
	public		int						getSiguiente()								{ return this.siguiente; }
	public		void					setSiguiente(int i)							{ this.siguiente = i; }
	private		static int CREAR = 1;
	private		static int MODIFICAR = 2;
	
		
	
	public JSReparacionesRecepcionadas() {
		super();
	}

	/**
	 * Carga la lista de reparaciones recepcionadas en la sección
	 * @return actionerror
	 * @throws SQLException
	 */
	@ProporcionaFuncionalidad(identificador = FactoriaFunciones.JEFE_SECCION_LISTAR_REP_RECEPCIONADAS)
	public String cargarReparaciones() throws SQLException {
		String res = SUCCESS;				
		QueryBuilder<Reparacion, Integer> reparacionQb = FactoriaDAO.getDao(Reparacion.class).queryBuilder();
		Where<Reparacion, Integer> wReparacionQb = reparacionQb.where();		
		wReparacionQb.eq(Reparacion.ID_SECCION_FIELD_NAME, this.getDatosEmpleado().getSeccion());
		wReparacionQb.and().isNotNull(Reparacion.FECHAENTRADA_FIELD_NAME);
		wReparacionQb.and().eq(Reparacion.VISTOBUENO_FIELD_NAME, false);
		this.setListaReparaciones(reparacionQb.query());
		return res;
	}

	/**
	 * Carga los trabajos de una reparación dada
	 * @return actionerror
	 * @throws SQLException
	 */
	@ProporcionaFuncionalidad(identificador = FactoriaFunciones.JEFE_SECCION_LISTAR_TRABAJOS_REP_RECEPCIONADA)
	public String cargarTrabajos() throws SQLException {
		String res = SUCCESS;		
		if ( this.getMecanicoSeleccionadoID() >= 0 ) {
			this.setMecanicoSeleccionado(FactoriaDAO.recuperar(Empleado.class, this.getMecanicoSeleccionadoID()));
		}
		this.setReparacionSeleccionadoID(this.getReparacionSeleccionadoID());
		this.setReparacionSeleccionado(FactoriaDAO.recuperar(Reparacion.class, this.getReparacionSeleccionadoID()));
		QueryBuilder<Trabajo, Integer> trabajoQb = FactoriaDAO.getDao(Trabajo.class).queryBuilder();
		Where<Trabajo, Integer> wTrabajoQb = trabajoQb.where();		
		wTrabajoQb.eq(Trabajo.ID_REPARACION_FIELD_NAME, this.getReparacionSeleccionado());
		this.setListaTrabajos(trabajoQb.orderBy(Reparacion.FECHAESTIMADA_FIELD_NAME, true).query());		
		return res;
	}

	/**
	 * Carga los mecánicos de una sección dada
	 * @return actionerror
	 * @throws SQLException
	 */
	@ProporcionaFuncionalidad(identificador = FactoriaFunciones.JEFE_SECCION_LISTAR_MECANICOS)
	public String cargarMecanicos() throws SQLException {
		String res = SUCCESS;		
		this.setNombreSeccion();
		
		QueryBuilder<Empleado, Integer> empleadoQb = FactoriaDAO.getDao(Empleado.class).queryBuilder();
		Where<Empleado, Integer> wEmpleadoQb = empleadoQb.where();
		wEmpleadoQb.eq(Empleado.CATEGORIA_FIELD_NAME, Empleado.Categoria.MECANICO);

		QueryBuilder<Usuario, Integer> usuarioQb = FactoriaDAO.getDao(Usuario.class).queryBuilder();
		Where<Usuario, Integer> wUsuarioQb = usuarioQb.where();
		wUsuarioQb.eq(Usuario.ACTIVO_FIELD_NAME, true);

		QueryBuilder<EmpleadoTaller, Integer> empleadoTallerQb = FactoriaDAO.getDao(EmpleadoTaller.class).queryBuilder();
		Where<EmpleadoTaller, Integer> wEmpleadoTallerQb = empleadoTallerQb.where();
		wEmpleadoTallerQb.eq(EmpleadoTaller.ID_SECCION_FIELD_NAME, this.getDatosEmpleado().getSeccion());
		
		QueryBuilder<Usuario, Integer> usuJOINeT = FactoriaDAO.getDao(Usuario.class).queryBuilder();
		usuJOINeT = usuarioQb.join(empleadoTallerQb);
		
		this.setListaMecanicos(empleadoQb.join(usuJOINeT).orderBy(Empleado.NOMBRE_FIELD_NAME, true).query());
		
		return res;	
	}
		
	/**
	 * Permite modificar un trabajo determinado
	 * @return actionerror
	 * @throws SQLException
	 */
	@ProporcionaFuncionalidad(identificador = FactoriaFunciones.JEFE_SECCION_MODIFICAR_TAREA)
	public String modificarTrabajo() throws SQLException {
		String res = SUCCESS;
		boolean alguno = false;
		if ( this.getTrabajoSeleccionadoID() == -1 ) {
			addActionError("No puede modificar ningún trabajo, porque no existe ninguno");
			res = ERROR;
		} else {
			if ( this.getMecanicoSeleccionadoID() >= 0 ) {
				alguno = true;						
			} else if ( !this.getFechaRecepcionString().isEmpty() ) {
				alguno = true;
			} else if ( !this.getFechaEstimadaString().isEmpty() ) {
				alguno = true;
			} else if ( !this.getDescripcion().isEmpty() ) {
				alguno = true;
			}
			if ( alguno ) {
				this.setTrabajoSeleccionado(FactoriaDAO.recuperar(Trabajo.class, this.getTrabajoSeleccionadoID()));
				SimpleDateFormat df = new SimpleDateFormat("dd/MM/yy");
				Date fecha = null;
				if ( this.getMecanicoSeleccionadoID() >= 0 ) {
					this.setMecanicoSeleccionado(FactoriaDAO.recuperar(Empleado.class, this.getMecanicoSeleccionadoID()));
					this.getTrabajoSeleccionado().setUsuario(this.getMecanicoSeleccionado().getUsuario());
				}
				if ( !this.getFechaEstimadaString().isEmpty() ) {
					try {
						fecha = df.parse(this.getFechaEstimadaString());
						this.getTrabajoSeleccionado().setFechaEstimada(fecha);
					} catch (ParseException e) {
						addActionError("Formato de la fecha estimada de fin erróneo");
						res = ERROR;
					}			
				}
				if ( !this.getDescripcion().isEmpty() ) {
					this.setDescripcion(this.getDescripcion());
					this.getTrabajoSeleccionado().setDescripcion(this.getDescripcion());
				}
				if ( res == SUCCESS) {
					this.getTrabajoSeleccionado().update();	
					this.getTrabajoSeleccionado().refresh();
					this.setNombreSeccion();				
					this.setReparacionSeleccionado(this.getTrabajoSeleccionado().getReparacion());
					this.setReparacionSeleccionadoID(this.getReparacionSeleccionado().getId());
					this.getReparacionSeleccionado().refresh();
					this.setParteSeleccionado(this.getReparacionSeleccionado().getParteTrabajo());
					this.setParteSeleccionadoID(this.getParteSeleccionado().getId());
					this.getParteSeleccionado().refresh();
					this.setMecanicoSeleccionado(this.getTrabajoSeleccionado().getUsuario().getEmpleado());
					this.setMecanicoSeleccionadoID(this.getMecanicoSeleccionado().getId());
					this.getMecanicoSeleccionado().refresh();
					this.siguiente = MODIFICAR;
				}
			} else {
				addActionError("No ha introducido ningún dato a modificar");
				res = ERROR;
			}
		}
		return res;
	}
	
	/** 
	 * Permite crear un nuevo trabajo para una reparación dada
	 * @return actionerror
	 * @throws SQLException
	 */
	@ProporcionaFuncionalidad(identificador = FactoriaFunciones.JEFE_SECCION_CREAR_TAREA)
	public String crearTrabajo() throws SQLException {
		String res = SUCCESS;
		this.setReparacionSeleccionado(FactoriaDAO.recuperar(Reparacion.class, this.getReparacionSeleccionadoID()));
		if ( this.getMecanicoSeleccionadoID() < 0 ) {
			addActionError("Falta el mecánico");
			res = ERROR;						
		}
		if ( this.getFechaEstimadaString().isEmpty() ) {
			addActionError("Falta la fecha estimada de fin");
			res = ERROR;						
		} else if ( this.getDescripcion().isEmpty() ) {
			addActionError("Falta la descripción del trabajo");
			res = ERROR;
		}
		if ( res == SUCCESS ) {
			this.setTrabajoSeleccionado(FactoriaDAO.recuperar(Trabajo.class, this.getTrabajoSeleccionadoID()));
			SimpleDateFormat df = new SimpleDateFormat("dd/MM/yy");
			Date fE = null;
			try {
				fE = df.parse(this.getFechaEstimadaString());
			} catch (ParseException e) {
				addActionError("Formato de la fecha estimada de fin erróneo");
				res = ERROR;
			}
			//Usuario u = this.getDatosEmpleado().getUsuario();
			this.setMecanicoSeleccionado(FactoriaDAO.recuperar(Empleado.class, this.getMecanicoSeleccionadoID()));
			Usuario u = this.getMecanicoSeleccionado().getUsuario();
			Reparacion r = this.getReparacionSeleccionado();
			String d = this.getDescripcion();
			//Trabajo t = Trabajo.crear(u, r, d, fR, fE, null,  false,  0,  null);
			Trabajo t = Trabajo.crear(u, r, d, null, fE, null,  false,  0,  null);
			if ( res == SUCCESS) {
				this.setTrabajoSeleccionado(t);				
				this.getTrabajoSeleccionado().refresh();
				this.setNombreSeccion();				
				this.setParteSeleccionado(this.getReparacionSeleccionado().getParteTrabajo());
				this.setParteSeleccionadoID(this.getParteSeleccionado().getId());
				this.setMecanicoSeleccionado(this.getTrabajoSeleccionado().getUsuario().getEmpleado());
				this.setMecanicoSeleccionadoID(this.getMecanicoSeleccionado().getId());				
				this.siguiente = CREAR;
			}
		} else {
			addActionError("No ha introducido ningún dato a modificar");
			res = ERROR;
		}
		return res;
	}
	
	
	@Override
	public void setSession(Map<String, Object> session) {
		userSession = session;
		try {
			this.setDatosEmpleado((Usuario) userSession.get("usuario"));
		} catch (SQLException e) {
			e.printStackTrace();
		}
	}

}
